package com.woniu.user.service.impl;

import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniu.common.exception.Assert;
import com.woniu.common.utils.JwtTemplate;
import com.woniu.common.entity.User;
import com.woniu.common.entity.dto.LoginDto;
import com.woniu.common.entity.dto.RegisterDto;
import com.woniu.common.entity.vo.LoginVo;
import com.woniu.user.mapper.UserMapper;
import com.woniu.user.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author mane
 * @since 2025-03-28
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private JwtTemplate jwtTemplate;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public LoginVo login(LoginDto loginDto) {
        //1。根据用户名查看是否有存在
        User user = getOne(new QueryWrapper<User>().eq("username", loginDto.getUsername()));
        Assert.error(user==null,"用户不存在");
        //2.验证密码是否正确
        boolean flag = BCrypt.checkpw(loginDto.getPassword(), user.getPassword());
        Assert.error(!flag,"密码错误");
        //3.调用生成token方法
        LoginVo loginVo = getLoginVo(user);

        return loginVo;
    }
    //使用jwt生成token
    private LoginVo getLoginVo(User user) {
        //封装数据，生成token
        HashMap<String, Object> map = new HashMap<>();
        map.put("userId", user.getId());
        map.put("username", user.getUsername());
        String token = jwtTemplate.createToken(map);
        //生成redis键
        String redisKey = "user:token:" + user.getId();
        // 存储到Redis
        redisTemplate.opsForValue().set(
                redisKey,
                token,
                Duration.ofMinutes(30));
        //返回结果
        LoginVo loginVo = new LoginVo();
        loginVo.setUsername(user.getUsername());
        loginVo.setToken(token);
        return loginVo;
    }

    @Override
    public void register(RegisterDto registerDto) {
        //1.判断用户是否存在
        User user = getOne(new QueryWrapper<User>().lambda().eq(User::getUsername, registerDto.getUsername()));
        Assert.error(user!=null,"用户已存在");
        //2.封装参数
        user = new User();
        user.setUsername(registerDto.getUsername());
        //3.将密码加密
        String pwd = BCrypt.hashpw(registerDto.getPassword());
        user.setPassword(pwd);
        user.setEmail(registerDto.getEmail());
        //4.注册
        save(user);
    }
}
